package cn.jeefast.modules.upload;

import cn.jeefast.common.exception.RRException;
import cn.jeefast.common.utils.R;
import cn.jeefast.util.ZipCompressor;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

@Slf4j
public class FileUtil {


    private static String imgWinPath = "C:/proj_imgs/mishop/imgs/upload/";
    private static String imgLinuxPath = "/mnt/app/web/baoxian/imgs/upload/";
    private static String imgWinPath2 = "C:/proj_imgs/mishop/imgs/";
    private static String imgLinuxPath2 = "/mnt/app/web/baoxian/imgs/";

    public static void main(String[] args) {
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            System.out.println(os);
        }
    }

    public static String getBasePath(HttpServletRequest request) {
        String basePath =
                request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
        return basePath;
    }

    /**
     * 单文件上传
     */
    public static String oneFile(MultipartFile file, String folder) {
        try {
            if (StringUtils.isBlank(file.getOriginalFilename())) {
                throw new RRException("请上传文件!");
            }
            String absPath = getPath();
            String returnPath = "";

            if (!cn.jeefast.modules.upload.QDUtil.isBlank(folder)) {
                absPath = absPath + folder + "/";
                returnPath = "/upload/" + folder + "/";
            } else {
                returnPath = "/upload/";
            }

            File mkdirsFile = new File(absPath);
            if (!mkdirsFile.exists()) {
                mkdirsFile.mkdirs();
            }
            String filename = file.getOriginalFilename();
            String nfileName = System.currentTimeMillis() + filename.substring(filename.lastIndexOf("."));
            File newFile = new File(absPath, nfileName);
//            log.error("absPath-->" + absPath);
//            log.error("newFile-->" + newFile);
            if (!newFile.exists()) {
                newFile.createNewFile();
            }
            file.transferTo(newFile);
            return returnPath + nfileName;
        } catch (IOException e) {
            e.printStackTrace();
            throw new RRException("文件保存失败，请联系管理员");
        }
    }

    /**
     * 多文件上传
     */
    public static String manyFile(MultipartFile[] file, String folder) {
        try {
            if (file.length == 0) {
                throw new RRException("请上传文件!");
            }
            String returnPath = "";
            String absPath = getPath();

            if (!cn.jeefast.modules.upload.QDUtil.isBlank(folder)) {
                absPath = absPath + folder + "/";
                returnPath = "/upload/" + folder + "/";
            } else {
                returnPath = "/upload/";
            }

            File mkdirsFile = new File(absPath);
            if (!mkdirsFile.exists()) {
                mkdirsFile.mkdirs();
            }
            String returnPaths = "";
            int i = 0;
            for (MultipartFile files : file) {
                String filename = files.getOriginalFilename();
                String nfileName =
                        System.currentTimeMillis() + "" + i + filename.substring(filename.lastIndexOf("."));
                File newFile = new File(absPath, nfileName);
                if (!newFile.exists()) {
                    newFile.createNewFile();
                }
                files.transferTo(newFile);
                if (i == 0) {
                    returnPaths = returnPath + nfileName;
                } else {
                    returnPaths = returnPaths + "," + returnPath + nfileName;
                }
                i++;
            }
            return returnPaths;
        } catch (IOException e) {
            e.printStackTrace();
            throw new RRException("文件保存失败，请联系管理员");
        }
    }

    /**
     * @Title: 单文件下载
     * @author: lzl
     */
    public static void downLoad(String name, HttpServletResponse response) {
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + name);
        byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            bis = new BufferedInputStream(new FileInputStream(
                    new File(getPath2() + name)));
            int i = bis.read(buff);

            while (i != -1) {
                os.write(buff, 0, buff.length);
                os.flush();
                i = bis.read(buff);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 删除
     */
    public static boolean deleteFile(String filename, String folder) {
        try {
            File file = new File(getPath() + folder, filename);
            return FileUtils.deleteQuietly(file);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取路径（win、linux）
     *
     * @return
     */
    public static String getPath() {
        String absPath = "";
        String returnPath = "";
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            absPath = imgWinPath;
        } else if (os.toLowerCase().startsWith("linux")) {
            absPath = imgLinuxPath;
        }
        return absPath;
    }

    /**
     * 获取下载模板路径（win、linux）
     *
     * @return
     */
    public static String getPath2() {
        String absPath = "";
        String returnPath = "";
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            absPath = imgWinPath2;
        } else if (os.toLowerCase().startsWith("linux")) {
            absPath = imgLinuxPath2;
        }
        return absPath;
    }

    /**
     * @param file1
     * @return String
     * @Title: 保存内容发布的PC端上传的图片
     * @author: lzl
     * @Description:
     */
    public static String saveSmallPicture(MultipartFile file1, String uploadFolder) {
        String path = "";
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            //如果图片大于500kb就压缩到500以下
            byte[] bytes = null;
            if (file1.getSize() > 500 * 1024) {
                bytes = compressPicForScale(file1.getBytes(), 500);// 图片小于300kb
            } else {
                bytes = file1.getBytes();
            }
            if (StringUtils.isBlank(file1.getOriginalFilename())) {
                throw new RRException("请上传文件!");
            }
            String absPath = getPath();

            if (!cn.jeefast.modules.upload.QDUtil.isBlank(uploadFolder)) {
                absPath = absPath + uploadFolder + "/";
                path = "/upload/" + uploadFolder + "/";
            } else {
                path = "/upload/";
            }

            File mkdirsFile = new File(absPath);
            if (!mkdirsFile.exists()) {
                mkdirsFile.mkdirs();
            }
            String filename = file1.getOriginalFilename();
            String nfileName = System.currentTimeMillis() + filename.substring(filename.lastIndexOf("."));
            File newFile = new File(absPath, nfileName);
            fos = new FileOutputStream(newFile);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
        } catch (Exception e) {
            e.printStackTrace();
            return path;
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    return path;
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    return path;
                }
            }
        }
        return path;
    }

    /**
     * 根据指定大小压缩图片
     *
     * @param imageBytes  源图片字节数组
     * @param desFileSize 指定图片大小，单位kb
     * @return 压缩质量后的图片字节数组
     */
    public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize) {
        if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < desFileSize * 1024) {
            return imageBytes;
        }
        long srcSize = imageBytes.length;
        double accuracy = getAccuracy(srcSize / 1024);
        try {
            while (imageBytes.length > desFileSize * 1024) {
                ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
                Thumbnails.of(inputStream)
                        .scale(accuracy)
                        .outputQuality(accuracy)
                        .toOutputStream(outputStream);
                imageBytes = outputStream.toByteArray();
            }
        } catch (Exception e) {

        }
        return imageBytes;
    }

    /**
     * 自动调节精度(经验数值)
     *
     * @param size 源图片大小
     * @return 图片压缩质量比
     */
    private static double getAccuracy(long size) {
        double accuracy;
        if (size < 900) {
            accuracy = 0.85;
        } else if (size < 2047) {
            accuracy = 0.6;
        } else if (size < 3275) {
            accuracy = 0.44;
        } else {
            accuracy = 0.4;
        }
        return accuracy;
    }

    public static R oneFile2(MultipartFile file, String folder) {
        try {
            String path = "";
            String size = "";
            if (StringUtils.isBlank(file.getOriginalFilename())) {
                throw new RRException("请上传文件!");
            }
            String absPath = getPath();
            String returnPath = "";

            if (!cn.jeefast.modules.upload.QDUtil.isBlank(folder)) {
                absPath = absPath + folder + "/";
                returnPath = "/upload/" + folder + "/";
            } else {
                returnPath = "/upload/";
            }

            File mkdirsFile = new File(absPath);
            if (!mkdirsFile.exists()) {
                mkdirsFile.mkdirs();
            }
            String filename = file.getOriginalFilename();
            String nfileName = System.currentTimeMillis() + filename.substring(filename.lastIndexOf("."));
            File newFile = new File(absPath, nfileName);
            if (!newFile.exists()) {
                newFile.createNewFile();
            }
            file.transferTo(newFile);
            path = returnPath + nfileName;
            size = file.getSize() + "";
            return R.ok().put("path", path).put("size", size);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RRException("文件保存失败，请联系管理员");
        }
    }

    public static R downLoadZip(String path, HttpServletResponse response) throws Exception {
        //先压缩指定文件夹的文件
        try {
            String absPath = getPath() + path;
            File mkdirsFile = new File(absPath);
            if (!mkdirsFile.exists()) {
                return R.error(500, "文件为空");
            }
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return R.error(500, "下载错误");
        }
    }
    public static void downLoadZip2(String path, HttpServletResponse response) throws Exception {
        //先压缩指定文件夹的文件
        try {
            String absPath = getPath() + path;
            File mkdirsFile = new File(absPath);
            if (!mkdirsFile.exists()) {
                return ;
            }
            ZipCompressor.compressedFile2(absPath, absPath + "zip", response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
